package example

import (
	"fmt"
	"gitee.com/youbeiwuhuan/gin-practice/go-ioc/ioc"
)

type Animals interface {
	Eat(food string) string
}

type Bird struct {
}

func (b *Bird) Eat(food string) string {

	fmt.Println("---------Bird------eat------" + food)

	return "Bird:" + food
}

type Eagle struct {
}

func (b *Eagle) Eat(food string) string {

	fmt.Println("---------Bird------eat------" + food)

	return "Bird:" + food
}

type BirdProxy struct {
	*Bird
	bird *Bird
}

func (b *BirdProxy) Eat(food string) string {

	fmt.Println("---------Bird------eat------" + food)

	return "Bird:" + food
}

func (b *BirdProxy) SetOriginBean(t interface{}) {
	b.bird = t.(*Bird)
}

func (b *BirdProxy) GetOriginBean() interface{} {
	return b.bird
}

func RunSimple() {
	// 注册单例bean,若容器中已经存在相同类型的bean则返回错误
	rErr := ioc.RegisterSingleton[Bird]("bird", &Bird{})
	if rErr != nil {
		panic(rErr)
	} else {
		fmt.Println("RegisterSingleton success")
	}

	bird, err := ioc.GetById[Bird]("bird")
	if err == nil {
		bird.Eat("peanut")
	} else {
		panic(err)
	}

	bird1, err := ioc.GetByType[Bird]()

	if err == nil {
		bird1.Eat("peanut1")
	} else {
		panic(err)
	}

}

func RunAop() {
	rErr := ioc.RegisterSingleton[Bird]("bird", &Bird{})
	if rErr != nil {
		panic(rErr)
	} else {
		fmt.Println("RegisterSingleton success")
	}

	bp := &BirdProxy{}
	// 在Go语言中，当使用类型嵌入(embedding)时，外层类型不能直接转换为内层嵌入类型，这是Go类型系统的一个设计特性。
	v, ok := interface{}(bp).(*Bird)
	if ok {
		fmt.Printf("------------%v", v)
	} else {
		fmt.Println("-------转换失败")
	}

	//ioc.RegisterAop[Bird](BirdProxy{},"bird")

}
